package problem;

import java.util.Stack;

public class S_130 {
    //被围绕的区域
    /*给定一个二维的矩阵，包含 'X' 和 'O'（字母 O）。
        找到所有被 'X' 围绕的区域，并将这些区域里所有的 'O' 用 'X' 填充。*/
    //1.dfs递归
    class Solution {
        //只要寻找到和边界连通的O就可以了
        public void solve(char[][] board) {
            if(board==null||board.length==0) return;
            int m=board.length;
            int n=board[0].length;
            for(int i=0;i<m;i++){
                for(int j=0;j<n;j++){
                    //从最边缘的O开始搜索
                    if(board[i][j]=='O'&&(i==0||j==0||i==m-1||j==n-1)){
                        dfs(board,i,j);
                    }
                }
            }
            for(int i=0;i<m;i++){
                for(int j=0;j<n;j++){
                    if(board[i][j]=='O') board[i][j]='X';
                    if(board[i][j]=='#') board[i][j]='O';
                }
            }
        }
        public void dfs(char[][] board,int i,int j){
            int m=board.length;
            int n=board[0].length;
            if(i<0||j<0||i>m-1||j>n-1||board[i][j]=='X'||board[i][j]=='#') return;
            board[i][j]='#';
            dfs(board,i-1,j);
            dfs(board,i,j-1);
            dfs(board,i,j+1);
            dfs(board,i+1,j);
        }
    }

    //2.dfs非递归
    class Solution1 {
        public class Pos{
            int i;
            int j;
            Pos(int i, int j) {
                this.i = i;
                this.j = j;
            }
        }
        public void solve(char[][] board) {
            if (board == null || board.length == 0) return;
            int m = board.length;
            int n = board[0].length;
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < n; j++) {
                    // 从边缘第一个是o的开始搜索
                    boolean isEdge = i == 0 || j == 0 || i == m - 1 || j == n - 1;
                    if (isEdge && board[i][j] == 'O') {
                        dfs(board, i, j);
                    }
                }
            }

            for (int i = 0; i < m; i++) {
                for (int j = 0; j < n; j++) {
                    if (board[i][j] == 'O') {
                        board[i][j] = 'X';
                    }
                    if (board[i][j] == '#') {
                        board[i][j] = 'O';
                    }
                }
            }
        }

        public void dfs(char[][] board, int i, int j) {
            Stack<Pos> stack = new Stack<>();
            stack.push(new Pos(i, j));
            board[i][j] = '#';
            while (!stack.isEmpty()) {
                // 取出当前stack 顶, 不弹出.
                Pos current = stack.peek();
                // 上
                if (current.i - 1 >= 0
                        && board[current.i - 1][current.j] == 'O') {
                    stack.push(new Pos(current.i - 1, current.j));
                    board[current.i - 1][current.j] = '#';
                    continue;
                }
                // 下
                if (current.i + 1 <= board.length - 1
                        && board[current.i + 1][current.j] == 'O') {
                    stack.push(new Pos(current.i + 1, current.j));
                    board[current.i + 1][current.j] = '#';
                    continue;
                }
                // 左
                if (current.j - 1 >= 0
                        && board[current.i][current.j - 1] == 'O') {
                    stack.push(new Pos(current.i, current.j - 1));
                    board[current.i][current.j - 1] = '#';
                    continue;
                }
                // 右
                if (current.j + 1 <= board[0].length - 1
                        && board[current.i][current.j + 1] == 'O') {
                    stack.push(new Pos(current.i, current.j + 1));
                    board[current.i][current.j + 1] = '#';
                    continue;
                }
                // 如果上下左右都搜索不到,本次搜索结束，弹出stack
                stack.pop();
            }
        }
    }

}
